<!DOCTYPE html>
<html>
<head>
	<meta charset=utf-8>
<!-- Documentation: version 0.2 from Jochen Stärk, 23.02.2013 
todo: show/hide menu bars, check classnames of new snippets, add from wiki:
 Show print preview

Zooming text documents

To select a printer or change the number of copies you can use a bit of UNO

Appending writer documents after one another

Search for a string and change it's font attributes

Substitute OpenOffice's save routine with a custom defined one

Delete paragraphs except the ones with tables

Get current page and jump to other pages

Open a writer document read only

Change the font attributes between two different search occurences

Have borders in spread sheets

Have additional sheets in spread sheets

Find text in spread sheets

Adding Hyperlinks in text tables

Reroute some key events to the java application embedding the openoffice frame

Add a toolbar icon to openoffice

Export every slide of a presentation ... as JPEG

Setting the native library path (libnativeview.so/nativeview.dll) of NOA 2.2 to something different than "lib"

Make hidden document visible

Get OpenOffice.org Setup information such as version or locale

Create a placholders and insert it into the text document

Replacing placholders

Change the value of a variable

Change the value of a form text field

Convert linked images (text graphic objects) into embedded ones

Advanced spread sheets methods

Embed open office in an applet 

Ideas for structurizing
Setup
Writer
	Ein- und Ausgabe
	UI
		Abschalten von Befehlen
	Manipulation
		Einfügen von Text
		Ändern von Textattributen
		Bilder
		Tabellen
		Platzhalter
		Formeln
Calc

-->
    <title>NOA-Libre Documentation</title>
    <style type="text/css">
    body {font-family:arial,verdana,sans}
    ul {list-style-type: none}
    pre, code {background-color:#f0f0f0}
    </style>
	</head>
<body>
<a name="top"></a>
<h1>Table of contents</h1>

<ul>


<li><a href='#what_is_noa-libre'>What is NOA-libre?</a>
<li><a href='#tutorial'>Tutorial</a>
<ul>
	<li><a href='#step1'>Step 1: Simple SWING application</a></li>
	<li><a href='#step2'>Step 2: Add OpenOffice.org Writer</a></li>
	<li><a href='#step3'>Step 3: Change Writer to Calc</a></li>
	<li><a href='#troubleshooting'>Troubleshooting</a></li>
</ul>
</li>

<li><a href='#snippets'>Snippets</a>
<ul>
	<li><a href='#writer'>OpenOffice Writer</a>
	<ul>
		<li><a href='#find_installation'>Find installation</a></li>
		<li><a href="#load_a_document">Load a document</a></li>
		<li><a href="#set_text">Set text</a></li>
		<li><a href='#change_font'>Change font</a></li>
		<li><a href='#find_text'>Find text</a></li>
		<li><a href='#search_and_replace'>Search and replace</a></li>
		<li><a href='#tables'>Tables</a></li>
		<li><a href='#construct_and_fill_table'>Construct and fill table</a></li>
		<li><a href='#more_table_operations'>More table operations</a></li>
		<li><a href='#formulas_in_writer_tables'>Formulas in Writer tables</a></li>
		<li><a href='#add_images'>Add images</a></li>
		<li><a href='#iterate_over_paragraphs_set_their_alignment'>Iterate over paragraphs, set their alignment</a></li>
		<li><a href='#ui_disable_commands'>UI: Disable commands</a></li>
	</ul><li><a href='#calc'>OpenOffice Calc</a>
	<ul>
		<li><a href='#spreadsheet'>Spreadsheet</a></li>
		<li><a href='#find_cell_by_name_set_formula'>Find cell by name, set formula</a></li>
	</ul><li><a href='#base'>OpenOffice Base</a>
	<ul>
	
		<li><a href='#base'>Base</a></li>
	
</ul>
<li><a href='#license'>License</a>

<h1>What is NOA-libre?</h1>
<a name='what_is_noa-libre'></a>
OpenOffice/LibreOffice have a great <abbr title="Application Programming Interface">API</abbr>, called <abbr title="Universal Network Objects">UNO</abbr>. 
As it is available over the network, it is actually much more than just an API, it's a fully-fledged middleware. 
<abbr title="Nice Office Access">NOA</abbr>-libre is a java wrapper around the client part of UNO, provides its own classes and methods but still allows to access the underlying UNO layer. 
By concentrating on Java, NOA-libre can take care of java-specific deployment
issues and it can be object oriented - one of UNO's primary target languages is ordinary C, so UNO can't be object oriented.
If you call UNO a middleware you could call NOA-libre the underwear: using NOA-libre you can access UNO much easier.
<br/>
This allows for the following use cases:

<ol>
<li><em>embedding</em> OpenOffice</li>
<li><em>remote-controlling</em> OpenOffice</li>
<li><em>extending</em> OpenOffice</li>
</ol>

Most of this documentation will focus on the most frequently used parts, embedding OpenOffice windows in your applications and remote controlling OpenOffice.
Remote-controlling means the OpenOffice window is - visible or hidden, as a separate window on your computer or anywhere else on the network - 
performing tasks in real time, like converting documents or replacing placeholders in OpenOffice templates and exporting <abbr title="Portable Document Format">PDFs</abbr>.
But with UNO/NOA-libre it is also possible to write functionality in Java and add this functionality in the OpenOffice window, e.g. as a button to
insert your mail footer or a selectbox to select the addressee from the list of your company's contacts obtained via LDAP. Your imagination is the limit :-)

<br/>
<a href='#top'>Back to top</a><br/>
<a name='tutorial'></a>
<h1>Tutorial</h1>

<a name='step1'></a>
<h2>Step 1: Simple SWING application</h2>

<ol>

<li>Start Eclipse.</li>
<li>Select file|new|java project, choose a 32 bit JDK, in my case e.g. 1.7, call the project LOEWE.</li>

<li>file|new|class. Name Loewe, superclass: javax.swing.JFrame, leave the  public static void main checkbox checked.</li>
<li>name Libre Office Embed Window Example, Loewe. Click finish.</li>
<li>Download and extract the noa-libre package. Copy noa-libre.jar from "dist" to "dist/lib" and copy the "lib" subdirectory below the "dist" directory to the workspace of your eclipse project,
as a sibling to the "src" folder created by eclipse, i.e. to  i.e. workspace/LOEWE/lib.</li>
<li>Right-click LOEWE in the package explorer, click properties and select "Java Build Path". In the tab libraries you should add external JAR files,
namely all JAR files in workspace/LOEWE/lib. Click OK to close the properties.</li>

<li> In the constructor we now add a JPanel, called NOApanel, to our screen and use <code>setVisible</code>, <code>setSize</code> and <code>setDefaultCloseOperation</code> to actually
show the window. We also alread add a WindowClosing listener - and we make sure the constructor is actually invoked. CTRL+O helps you import the classes you need.
Your code should now look like this:


<pre>
<code>
import java.awt.GridLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;
//(2a*)
//(3a*)

public class Loewe extends JFrame {

	private JPanel NOApanel;
//(2b*)
//(3b*)
	public Loewe() {
		setVisible(true);
		setSize(500,500);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e) {
//(2c)
				super.windowClosing(e);
			}
			
			
		});
		
		NOApanel=new JPanel();
		
		getContentPane().setLayout(new GridLayout());
		getContentPane().add(NOApanel);
//(2d)
//(3d*)
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Loewe l=new Loewe();

	}

}
</code>
</pre>
</li>

<li>(Please note that I have added comments like //(2d) to mark the places for later insertions.)<br/>We now create a new run configuration: Run|Run configurations, click the new icon at the top left over the input field
("New launch configuration"). Click run and you should see an empty, gray window. Nothing yet spectacular.
<br/>
<img src='step1.png' alt='Results of Step 1, a empty java window.'><br/>

</li>
</ol>
<a href='#top'>Back to top</a><br/>
<a name='step2'></a>
<h2>Step 2: Add OpenOffice.org Writer</h2>
<ol>
<li>
We'll now use an IApplicationAssistant to find the local installation of your OpenOffice instance.
This will be put in a HashMap we call configuration as IOfficeApplication.APPLICATION_HOME_KEY. 
IOfficeApplication.APPLICATION_TYPE_KEY is always IOfficeApplication.LOCAL_APPLICATION unless you want to connect 
to a different OpenOffice instance running over the network.
</li>
<li>
With this "configuration" hasmap we can use <code>OfficeApplicationRuntime.getApplication(configuration);</code> to obtain 
the <em>officeApplication</em> from NOA-libre. We will activate the connection and add a <em>NativeView</em>.
We will need to tell the NativeView (and the IApplicationAssistant in the very first place) where to find it's NOA-libre libraries.
</li>
<li>
We add this NativeView to our NOApanel and construct a new <em>OfficeFrame</em> from it. And this OfficeFrame is now finally the
parameter we need to invoke <code>(ITextDocument)officeApplication.GetDocumentService().constructNewDocument(officeFrame,  Idocument.WRITER, DocumentDescriptor.DEFAULT);</code>
which will finally and visually embed OpenOffice. We're almost there:
</li>
<li>
If you started the application by now you would be able to resize the window - but that would not propagate to the embedded OpenOffice.
so we add a ComponentListener on the componentResized event and tell our NativeView to adapt.
<br/>We'll do this after adding the panel to the content pane, i.e. replace //(2d)
by

<pre>
<code>
                 IApplicationAssistant ass;
                 try {
                         ass = new ApplicationAssistant(System.getProperty("user.dir")
                         	+File.separator+"lib");
                         ILazyApplicationInfo[] ila=ass.getLocalApplications();
 
                         HashMap&lt;String, String&gt; configuration=new HashMap&lt;String, String&gt;();
                         configuration.put(IOfficeApplication.APPLICATION_HOME_KEY,
 				   ila[0].getHome());
                         configuration.put(IOfficeApplication.APPLICATION_TYPE_KEY, 
 				   IOfficeApplication.LOCAL_APPLICATION);
                         
                         officeApplication = OfficeApplicationRuntime.
                         getApplication(configuration);
                         officeApplication.activate();
                         nat=new NativeView(System.getProperty("user.dir")+File.separator+"lib");
                         nat.setSize(NOApanel.getWidth(), NOApanel.getHeight());
                         NOApanel.addComponentListener(new ComponentAdapter() {
 
                                 @Override
                                 public void componentResized(ComponentEvent e) {
                                         nat.setPreferredSize(new
                                          Dimension(NOApanel.getWidth(),
 							NOApanel.getHeight()));
                                         NOApanel.getLayout().layoutContainer(NOApanel);
                                         super.componentResized(e);
                                 }
                                 
                         });
 
                  NOApanel.add(nat);
                  NOApanel.setVisible(true);
 		 	  officeFrame=officeApplication.getDesktopService().
 				constructNewOfficeFrame(nat);
                  document=/*(3f)*/(ITextDocument)officeApplication.
 				getDocumentService().
 				constructNewDocument(officeFrame, /*(3g)*/ IDocument.WRITER,
 							DocumentDescriptor.DEFAULT);
//(3c)
          } catch (OfficeApplicationException e1) {
                         e1.printStackTrace();
          } catch (DesktopException e1) {
                         e1.printStackTrace();
          } catch (NOAException e1) {
						e1.printStackTrace();
		  }
</code>
</pre>
</li>
<li>
If you pasted the above code some CTRL+SHIFT+O will get you the imports you need - something we would otherwise have to do by
replacing //(2a*) with
<pre>
<code>
import java.io.File;
import java.util.HashMap;
import ag.ion.bion.officelayer.NativeView;
import ag.ion.bion.officelayer.application.IApplicationAssistant;
import ag.ion.bion.officelayer.application.ILazyApplicationInfo;
import ag.ion.bion.officelayer.application.IOfficeApplication;
import ag.ion.bion.officelayer.application.OfficeApplicationException;
import ag.ion.bion.officelayer.application.OfficeApplicationRuntime;
import ag.ion.bion.officelayer.desktop.DesktopException;
import ag.ion.bion.officelayer.document.DocumentDescriptor;
import ag.ion.bion.officelayer.document.IDocument;
import ag.ion.bion.officelayer.internal.application.ApplicationAssistant;
import ag.ion.bion.officelayer.text.ITextDocument;
import ag.ion.noa.NOAException;

</code>
</pre>
. Four quick fixes (create field) will also take the burden from us to 
replace //(2b*) with
<pre>
<code>
         private IOfficeApplication officeApplication=null;
         private NativeView nat;
         private IFrame officeFrame;
         private /*(3e)*/ITextDocument document=null;
 
</code>
</pre>. 
Please just note - and maybe add - the /*(3e)*/ replacement indicator.
You might already have thought that the replacement indicators marked with asterisk, i.e. //(2b*) can be conducted by eclipse itself.
</li>
<li>
There is one last thing: The connection between the OpenOffice front end and middleware is delicate, i.e. the connections
must be managed properly because many of them require OpenOffice to start - and listen - when they open (activate) and
close down when they deactivate. <br/>

If you were too fast for this step and started already, your OpenOffice might get stuck and you'll find help in the 
<a href='#close_and_deactivate'>troubleshooting</a> section.

<br/>


So we <em>need</em> to be nice and helpful and close the document as well as deactivate the officeApplication when 
we go, i.e. in our windowClosing event. So please add in the windowClosing before the <code>super.windowClosing(e);</code>, i.e. replace //(2c) with
<pre>
<code>
                                 if (document!=null) {
                                         document.close();
                                 }
                                 if (officeApplication!=null) {
                                         try {
                                                 officeApplication.deactivate();
                                         } catch (OfficeApplicationException e1) {
                                                 // TODO Auto-generated catch block
                                                 e1.printStackTrace();
                                         }
                                 }
 
</code>
</pre>That's it.<br/>
Start and you will have a OpenOffice embedded in your Java Frame. It will even react - as you can see I typed "Hello World!".
<br/>
<img src='step2.png' alt='Results of Step 2, a embedded OpenOffice Writer.'><br/>
This is it, most of you (I hope) are already eager to get started. The good news is: after this foundation everything is much easier.
On this basis you can now programmatically set text, change attributes or load writer documents, insert tables or images, change which options the
embedded OpenOffice offers to the users, print, export and import files and much more.
<br/>
You could e.g. replace constructNewDocument in the context of the 3f, 3g lines with 

<pre>
<a name="load"></a>
<code>
			document = /* (3f) */(ITextDocument) officeApplication
					.getDocumentService().loadDocument(officeFrame, 
							"C:\\Users\\jstaerk\\Documents\\brief_adac.odt", DocumentDescriptor.DEFAULT);
</code>
</pre>
You would only have to replace the catch for NOAException with one for DocumentException.
If you just left out the "officeFrame" parameter, it would still work - but in this case, a separate OpenOffice Window would open with the 
document, which demonstrates how closely related embedding and remote-controlling OpenOffice are.

<br/>
Without loading any document the whole file will look like this:
<pre>
<code>
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.HashMap;

import javax.swing.JFrame;
import javax.swing.JPanel;

import ag.ion.bion.officelayer.NativeView;
import ag.ion.bion.officelayer.application.IApplicationAssistant;
import ag.ion.bion.officelayer.application.ILazyApplicationInfo;
import ag.ion.bion.officelayer.application.IOfficeApplication;
import ag.ion.bion.officelayer.application.OfficeApplicationException;
import ag.ion.bion.officelayer.application.OfficeApplicationRuntime;
import ag.ion.bion.officelayer.desktop.DesktopException;
import ag.ion.bion.officelayer.desktop.IFrame;
import ag.ion.bion.officelayer.document.DocumentDescriptor;
import ag.ion.bion.officelayer.document.IDocument;
import ag.ion.bion.officelayer.internal.application.ApplicationAssistant;
import ag.ion.bion.officelayer.text.ITextDocument;
import ag.ion.noa.NOAException;

import com.sun.star.sheet.XSheetCellCursor;
import com.sun.star.sheet.XSpreadsheet;
import com.sun.star.sheet.XSpreadsheets;

//(2a*)
//(3a)

public class Loewe extends JFrame {

	private JPanel NOApanel;
	private IOfficeApplication officeApplication;
	private NativeView nat;
	private IFrame officeFrame;
	private ITextDocument /* (3e) */document;
	private XSpreadsheets spreadsheets;
	private XSpreadsheet spreadSheet1;
	private XSheetCellCursor cellCursor;

	// (2b*)
	// (3b)
	public Loewe() {
		setVisible(true);
		setSize(500, 500);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e) {
				if (document != null) {
					document.close();
				}
				if (officeApplication != null) {
					try {
						officeApplication.deactivate();
					} catch (OfficeApplicationException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
				super.windowClosing(e);
			}

		});

		NOApanel = new JPanel();

		getContentPane().setLayout(new GridLayout());
		getContentPane().add(NOApanel);
		IApplicationAssistant ass;
		try {
			ass = new ApplicationAssistant(System.getProperty("user.dir")
					+ File.separator + "lib");
			ILazyApplicationInfo[] ila = ass.getLocalApplications();

			HashMap<String, String> configuration = new HashMap<String, String>();
			configuration.put(IOfficeApplication.APPLICATION_HOME_KEY,
					ila[0].getHome());
			configuration.put(IOfficeApplication.APPLICATION_TYPE_KEY,
					IOfficeApplication.LOCAL_APPLICATION);

			officeApplication = OfficeApplicationRuntime
					.getApplication(configuration);
			officeApplication.activate();
			nat = new NativeView(System.getProperty("user.dir")
					+ File.separator + "lib");
			nat.setSize(NOApanel.getWidth(), NOApanel.getHeight());
			NOApanel.addComponentListener(new ComponentAdapter() {

				@Override
				public void componentResized(ComponentEvent e) {
					nat.setPreferredSize(new Dimension(NOApanel.getWidth(),
							NOApanel.getHeight()));
					NOApanel.getLayout().layoutContainer(NOApanel);
					super.componentResized(e);
				}

			});

			NOApanel.add(nat);
			NOApanel.setVisible(true);
			officeFrame = officeApplication.getDesktopService()
					.constructNewOfficeFrame(nat);
			document = /* (3f) */(ITextDocument) officeApplication
					.getDocumentService().constructNewDocument(officeFrame, /*(3g)*/
							IDocument.WRITER, DocumentDescriptor.DEFAULT);
		} catch (OfficeApplicationException e1) {
			e1.printStackTrace();
		} catch (DesktopException e1) {
			e1.printStackTrace();
		} catch (NOAException e1) {
			e1.printStackTrace();
		}

	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Loewe l = new Loewe();

	}

}

</code>
</pre>



</li></ol>

<a href='#top'>Back to top</a><br/>
<a name='step3'></a>
<h2>Step 3: Change Writer to Calc</h2>

In the last step of this tutorial we switch from OpenOffice Writer to OpenOffice Calc.
This is easy but the Calc functions in NOA-libre do not completely cover what you usually need for 
your work on spreadsheets, which is a great opportunity to have a look how to access the underlying UNO layer with NOA-libre.

<ol>
<li>Change 	
<pre>
<code>
private ITextDocument /*(3e)*/ document; 
</code>
</pre>
to 	
<pre>
<code>
private ISpreadsheetDocument /*(3e)*/ document;
</code>
</pre>
and

<pre>
<code>
document=/*(3f)*/(ITextDocument)officeApplication.
</code>
</pre>
to 	
<pre>
<code>
document=/*(3f)*/(ISpreadsheetDocument)officeApplication.
</code>
</pre>

as well as 

<pre>
<code>
		constructNewDocument(officeFrame, /*(3g)*/ IDocument.WRITER,

</code>
</pre>
to 	
<pre>
<code>
		constructNewDocument(officeFrame, /*(3g)*/ IDocument.CALC,

</code>
</pre>
CTRL+SHIFT+O to import ISpreadsheetDocument and you accomplished 
an important first step - if you started it at this stage you would already see an empty OpenOffice Calc.
<br/>
<img src='step3a.png' alt='Results of Step 3a, a embedded OpenOffice Calc.'><br/>


<br/>
But this is just where the fun starts, unlike with text documents where much functionality is covered by
NOA-libre itself, to add some content to our spread sheet we have to dive into UNO.
<br/>

For further information, download <a href='http://www.openoffice.org/download/other.html#tested-sdk'>OpenOffice's SDK</a> and/or
have a look at the according <a href='http://wiki.openoffice.org/wiki/Documentation/DevGuide/OpenOffice.org_Developers_Guide'>
Developer's Guide</a> for a comprehensive UNO reference.


</li>

<li>
Now, as a spreadsheet document consists of different spread sheets (shown in the tabs at the 
bottom of Calc) we're going to get all Sheets (<code>document.getSpreadsheetDocument().getSheets()</code>), 
and then we get the name of the first one (getElementNames()) to
have it stored in a spreadSheet1 variable. Then we can create a cellCursor, get the cells by
position and set their integer or float value. To set a string value, we have to create
a XText with <code>UnoRuntime.queryInterface(XText.class, cell)</code> first.
The fun thing is that all types prefixed with X are from the UNO-Layer of NOA-libre, so 
we're already using UNO functionality.<br/>

Or, in other words, replace //(3c) with
<pre>
<code>
                  spreadsheets=document.getSpreadsheetDocument().getSheets();
                  spreadSheet1=(XSpreadsheet)
                          UnoRuntime.queryInterface(XSpreadsheet.class,
       		  spreadsheets.getByName(spreadsheets.getElementNames()[0]));
                         
                  cellCursor = spreadSheet1.createCursor();
                  XCell cell=null;
                  cell=cellCursor.getCellByPosition(0, 1);
                  cell.setValue(10);
                  cell=cellCursor.getCellByPosition(0, 2);
                  cell.setValue(12.2);
                  cell=cellCursor.getCellByPosition(1, 1);
                  cell.setValue(22.2);
                  cell=cellCursor.getCellByPosition(0, 0);
                  XText cellText=UnoRuntime.queryInterface(XText.class, cell);
                         
                  cellText.setString("Accounts receivables");
</code>
</pre>

</li>
<li>
Intuitively using CTRL+SHIFT+O you should already have replace //(3a*) with
<pre>
<code>
 import com.sun.star.container.NoSuchElementException;
 import com.sun.star.lang.IndexOutOfBoundsException;
 import com.sun.star.lang.WrappedTargetException;
 import com.sun.star.sheet.XSheetCellCursor;
 import com.sun.star.sheet.XSpreadsheet;
 import com.sun.star.sheet.XSpreadsheets;
 import com.sun.star.table.XCell;
 import com.sun.star.text.XText;
 import com.sun.star.uno.UnoRuntime;
 import ag.ion.bion.officelayer.application.OfficeApplicationRuntime;
 import ag.ion.bion.officelayer.desktop.DesktopException;
 import ag.ion.bion.officelayer.document.DocumentDescriptor;
 import ag.ion.bion.officelayer.document.DocumentException;
 import ag.ion.bion.officelayer.internal.application.ApplicationAssistant;
 import ag.ion.bion.officelayer.spreadsheet.ISpreadsheetDocument;


</code>
</pre>
</li>
<li>
and applied the quick fixes to create the fields mentioned in //(3b*) with
<pre>
<code>
    private XSpreadsheets spreadsheets;
    private XSpreadsheet spreadSheet1;
    private XSheetCellCursor cellCursor;
 
</code>
</pre>
Just watch out that spreadsheets is a XSpreadsheets and not a Object.<br/>
As you can see: they are all UNO.
</li>
<li>

A bit of try/catch quick fixing (add catch to surrounding try) should also have added the neccessary catches , i.e. 
<br/>
replace //(3d*) with
<pre>
<code>

          } catch (IndexOutOfBoundsException e1) {
                         e1.printStackTrace();
          } catch (NoSuchElementException e1) {
                         e1.printStackTrace();
          } catch (WrappedTargetException e1) {
                         e1.printStackTrace();
          }
                 
</code>
</pre>
Save, run, lean back and enjoy: You have completed the tutorial.
<br/>
<img src='step3b.png' alt='The finished OpenOffice Calc with sample values.'><br/>

The whole file will now look like this:
<pre>
<code>
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.HashMap;

import javax.swing.JFrame;
import javax.swing.JPanel;

import ag.ion.bion.officelayer.NativeView;
import ag.ion.bion.officelayer.application.IApplicationAssistant;
import ag.ion.bion.officelayer.application.ILazyApplicationInfo;
import ag.ion.bion.officelayer.application.IOfficeApplication;
import ag.ion.bion.officelayer.application.OfficeApplicationException;
import ag.ion.bion.officelayer.application.OfficeApplicationRuntime;
import ag.ion.bion.officelayer.desktop.DesktopException;
import ag.ion.bion.officelayer.desktop.IFrame;
import ag.ion.bion.officelayer.document.DocumentDescriptor;
import ag.ion.bion.officelayer.document.IDocument;
import ag.ion.bion.officelayer.internal.application.ApplicationAssistant;
import ag.ion.bion.officelayer.spreadsheet.ISpreadsheetDocument;
import ag.ion.noa.NOAException;

import com.sun.star.container.NoSuchElementException;
import com.sun.star.lang.IndexOutOfBoundsException;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.sheet.XSheetCellCursor;
import com.sun.star.sheet.XSpreadsheet;
import com.sun.star.sheet.XSpreadsheets;
import com.sun.star.table.XCell;
import com.sun.star.text.XText;
import com.sun.star.uno.UnoRuntime;

//(2a*)
//(3a)

public class Loewe extends JFrame {

	private JPanel NOApanel;
	private IOfficeApplication officeApplication;
	private NativeView nat;
	private IFrame officeFrame;
	private ISpreadsheetDocument /* (3e) */document;
	private XSpreadsheets spreadsheets;
	private XSpreadsheet spreadSheet1;
	private XSheetCellCursor cellCursor;

	// (2b*)
	// (3b)
	public Loewe() {
		setVisible(true);
		setSize(500, 500);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e) {
				if (document != null) {
					document.close();
				}
				if (officeApplication != null) {
					try {
						officeApplication.deactivate();
					} catch (OfficeApplicationException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
				super.windowClosing(e);
			}

		});

		NOApanel = new JPanel();

		getContentPane().setLayout(new GridLayout());
		getContentPane().add(NOApanel);
		IApplicationAssistant ass;
		try {
			ass = new ApplicationAssistant(System.getProperty("user.dir")
					+ File.separator + "lib");
			ILazyApplicationInfo[] ila = ass.getLocalApplications();

			HashMap<String, String> configuration = new HashMap<String, String>();
			configuration.put(IOfficeApplication.APPLICATION_HOME_KEY,
					ila[0].getHome());
			configuration.put(IOfficeApplication.APPLICATION_TYPE_KEY,
					IOfficeApplication.LOCAL_APPLICATION);

			officeApplication = OfficeApplicationRuntime
					.getApplication(configuration);
			officeApplication.activate();
			nat = new NativeView(System.getProperty("user.dir")
					+ File.separator + "lib");
			nat.setSize(NOApanel.getWidth(), NOApanel.getHeight());
			NOApanel.addComponentListener(new ComponentAdapter() {

				@Override
				public void componentResized(ComponentEvent e) {
					nat.setPreferredSize(new Dimension(NOApanel.getWidth(),
							NOApanel.getHeight()));
					NOApanel.getLayout().layoutContainer(NOApanel);
					super.componentResized(e);
				}

			});

			NOApanel.add(nat);
			NOApanel.setVisible(true);
			officeFrame = officeApplication.getDesktopService()
					.constructNewOfficeFrame(nat);
			document = /* (3f) */(ISpreadsheetDocument) officeApplication
					.getDocumentService().constructNewDocument(officeFrame, /*(3g)*/
							IDocument.CALC, DocumentDescriptor.DEFAULT);
			spreadsheets = document.getSpreadsheetDocument().getSheets();
			spreadSheet1 = (XSpreadsheet) UnoRuntime.queryInterface(
					XSpreadsheet.class,
					spreadsheets.getByName(spreadsheets.getElementNames()[0]));

			cellCursor = spreadSheet1.createCursor();
			XCell cell = null;
			cell = cellCursor.getCellByPosition(0, 1);
			cell.setValue(10);
			cell = cellCursor.getCellByPosition(0, 2);
			cell.setValue(12.2);
			cell = cellCursor.getCellByPosition(1, 1);
			cell.setValue(22.2);
			cell = cellCursor.getCellByPosition(0, 0);
			XText cellText = UnoRuntime.queryInterface(XText.class, cell);

			cellText.setString("Accounts receivables");
		} catch (OfficeApplicationException e1) {
			e1.printStackTrace();
		} catch (DesktopException e1) {
			e1.printStackTrace();
		} catch (NOAException e1) {
			e1.printStackTrace();
		} catch (NoSuchElementException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (WrappedTargetException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IndexOutOfBoundsException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Loewe l = new Loewe();

	}

}

</code>
</pre>
<a href='#top'>Back to top</a><br/>
<a name='troubleshooting'></a>
<h2>Troubleshooting</h2>
Some typical mistakes include:
<ol>

<li><a name='close_and_deactivate'></a>If you don't <strong>close and deactivate</strong>, the old zombie openoffice listening instance from the test before will greedily 
eat all data supposed to be sent to the currently running instance, which will make this - current - instance of your test program
a zombie as well if this accidentally happens, reboot - or check the process list for "soffice" or "soffice.bin" and kill your 
zombies - and start and close a clean standalone OpenOffice Writer after you did because the zombies usually corrupted the 
documents which OpenOffice would assist you to recover. You can manually skip this recovery if you like but if your program
embeds OpenOffice while it is still in "recovery pending" mode it might just fail because your software does not understand what
OpenOffice says and OpenOffice does not understand what your program answers.
</li>
<li>
no ICE_JNIRegistry in java.library.path: The library path parameter for ApplicationAssistant might be missing or incorrect.
</li>
<li>
Exception in thread "main" java.lang.UnsatisfiedLinkError: no nativeview in java.library.path: The library path parameter for nativeView might be missing or incorrect.
</li>
<li>
ArrayIndexOutOfBoundsException bei ILazyApplicationInfo[0]: Potentially you are not using a 32 but 64 bit Java.
</li>
<li>
ag.ion.bion.officelayer.application.OfficeApplicationException: Configuration for office application is missing:
You might have mistyped the configuration, e.g. with a erroneous <code>configuration.put(IOfficeApplication.APPLICATION_TYPE_KEY, IOfficeApplication.APPLICATION_TYPE_KEY);</code>
</li>
<li>
If includes can not be found, you might not have copied noa-libre.jar from dist/ to workspace/LOEWE/lib - or you forgot to
include it in the project options.
</li>
</ol>


<br/>
<a href='#top'>Back to top</a><br/>
<a name="snippets"></a>
<h2>Snippets</h2>


<a name="writer"></a>
<h2>OpenOffice Writer</h2>

<a name="find_installation"></a><h3>Find installation</h3>

As used in the <a href='#tutorial'>tutorial</a> this will look for OpenOffice in it's default locations and print where it has been found:
<pre>
<code>
	import ag.ion.bion.officelayer.application.IApplicationAssistant;
	import ag.ion.bion.officelayer.application.ILazyApplicationInfo;

//...

	IApplicationAssistant applicationAssistant = new ApplicationAssistant();
	ILazyApplicationInfo appInfo = applicationAssistant.getLatestLocalApplication();
	if (appInfo!=null) { // A Openoffice.org was found
		System.out.println(appInfo.getHome());
	}

</code>
</pre>
Please note in NOA-libre, contrary to plain NOA, getLatestLocalApplication has to be replaced by 
getLatestLocalLibreOfficeApplication respectively getLatestLocalOpenOfficeOrgApplication.

This is some source code which should obtain the libreoffice/openoffice installation with the highest version number:
<pre>
<code>
public static ILazyApplicationInfo getOfficeInfo() {
		IApplicationAssistant applicationAssistant;
		ILazyApplicationInfo appInfo=null, LappInfo=null, OappInfo=null; 
		try {
			applicationAssistant = new ApplicationAssistant();
			LappInfo = applicationAssistant.getLatestLocalLibreOfficeApplication();
			OappInfo = applicationAssistant.getLatestLocalOpenOfficeOrgApplication();
			appInfo=OappInfo;// take the latest openoffice installation unless libreoffice is also installed in a higher version
			if (appInfo==null) {
				appInfo=LappInfo;
			}
			if ((LappInfo!=null)&&(OappInfo!=null)) {
				if (LappInfo.getMajorVersion()>OappInfo.getMajorVersion()) {
					appInfo=LappInfo;	
				}
				if (LappInfo.getMajorVersion()==OappInfo.getMajorVersion()) {
					if (LappInfo.getMinorVersion()>OappInfo.getMinorVersion()) {
						appInfo=LappInfo;	
					}
				}
			}
		} catch (OfficeApplicationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return appInfo;
	}
</code>
</pre>
<a href='#top'>Back to top</a><br/>
<a name="load_a_document"></a><h3>Load a document</h3>
Have a look at the according part in the <a href='#load'>tutorial</a>

<a href='#top'>Back to top</a><br/>
<a name="set_text"></a><h3>Set text</h3>
<a href="../examples/text/Snippet18-setText.java">Snippet 18</a> shows three ways how to add
text to a document, using TextService:
<ol><li>
<pre>
<code>
			// Quick and dirty
			document.getTextService().getText().setText("Hello World Test Text");
			String temp = document.getTextService().getText().getText();
			document.getTextService().getText().setText(temp + "\n" + "Next Line in text");	
</code>
</pre></li>
<li> using textCursor
<pre>
<code>

			// first we create a text cursor 
			ITextCursor textCursor = document.getTextService().getCursorService().getTextCursor();
			
			// then we go to the end of the text
			textCursor.gotoEnd(false);
			// and now we use setText on textCursor:

	  		textCursor.getEnd().setText("One..."); //we place the text
	  		textCursor.getEnd().setText("\n"); // and we wrap the line
	  		textCursor.getEnd().setText("Two..."); //we place the text
	  		textCursor.getEnd().setText("\n"); // and we wrap the line
			
</code>
</pre></li>

<li> ... and constructing complete paragraphs
<pre>
<code>

			// we still need the text cursor 
			// then we create a paragraph
			IParagraph paragraph=document.getTextService().getTextContentService().constructNewParagraph();
			// insert the paragraph
			document.getTextService().getTextContentService().insertTextContent(textCursor.getEnd(), paragraph);
			// and finally set the text
			paragraph.setParagraphText("Hello World!");
			
</code>
</pre></li>


</ol>
<a href='#top'>Back to top</a><br/>


<a name="change_font"></a><h3>Change Font</h3>
Also used in <a href="../examples/text/Snippet18-setText.java">Snippet 18</a>

<pre>
<code>

			paragraph.getCharacterProperties().setFontSize(36);
			paragraph.getCharacterProperties().setFontUnderline(true);
			// setFontColor is apparently expecting RGB values
			paragraph.getCharacterProperties().setFontColor(0xff8080);

</code>
</pre>
To set the font family, you have to take a small excurse into UNO:
<pre>
<code>
paragraph.getCharacterProperties().getXPropertySet().setPropertyValue("CharFontName","Arial");
</code>
</pre>


<a href='#top'>Back to top</a><br/>
<a name="find_text"></a><h3>
Find text
</h3>

<pre>
<code>
/*
 * Last changes made by $Author: andreas $, $Date: 2006-10-04 14:14:28 +0200 (Mi, 04 Okt 2006) $
 */
import ag.ion.bion.officelayer.application.IOfficeApplication;
import ag.ion.bion.officelayer.application.OfficeApplicationException;
import ag.ion.bion.officelayer.application.OfficeApplicationRuntime;

import ag.ion.bion.officelayer.document.DocumentDescriptor;
import ag.ion.bion.officelayer.document.IDocument;
import ag.ion.bion.officelayer.document.IDocumentService;

import ag.ion.bion.officelayer.text.ITextDocument;
import ag.ion.bion.officelayer.text.ITextRange;

import ag.ion.noa.NOAException;

import ag.ion.noa.search.ISearchResult;
import ag.ion.noa.search.SearchDescriptor;

import ag.ion.noa.text.TextRangeSelection;

import java.util.HashMap;

/**
 * This code snippet shows how it is possible to search
 * within a text document.
 * 
 * @author Andreas Bröker
 * @version $Revision: 10398 $
 * @date 16.07.2006
 */
public class Snippet12 {

	/*
	 * The path to the office application, in this case on a windows system.
	 * 
	 * On a Linux system this would look like: 
	 * => private final static String officeHome = "/usr/lib/ooo-2.0"; 
	 */
	private final static String OPEN_OFFICE_ORG_PATH = "C:\\Programme\\OpenOffice.org 2.0"; 
		
	public static void main(String[] args) {
		try {
			HashMap configuration = new HashMap();
			configuration.put(IOfficeApplication.APPLICATION_HOME_KEY, OPEN_OFFICE_ORG_PATH);
			configuration.put(IOfficeApplication.APPLICATION_TYPE_KEY, IOfficeApplication.LOCAL_APPLICATION);
			IOfficeApplication officeAplication = OfficeApplicationRuntime.getApplication(configuration);	
			officeAplication.setConfiguration(configuration);
			officeAplication.activate();
			IDocumentService documentService = officeAplication.getDocumentService();
			IDocument document = documentService.constructNewDocument(IDocument.WRITER, DocumentDescriptor.DEFAULT);
			ITextDocument textDocument = (ITextDocument)document;
			//First some text ...
			textDocument.getTextService().getText().setText("This is a text content for a search example with NOA.");
			
			//OK - now we need a search query
			SearchDescriptor searchDescriptor = new SearchDescriptor("NOA");
			searchDescriptor.setIsCaseSensitive(true);
			//Perform the search ...
			ISearchResult searchResult = textDocument.getSearchService().findFirst(searchDescriptor);
			if(!searchResult.isEmpty()) {
				//...and now select the result
				ITextRange[] textRanges = searchResult.getTextRanges();
				textDocument.setSelection(new TextRangeSelection(textRanges[0]));
			}
		} 
		catch (OfficeApplicationException exception) {
			exception.printStackTrace();
		} 
		catch (NOAException exception) {
			exception.printStackTrace();
		}
	}

}
</code>
</pre>

<a href='#top'>Back to top</a><br/>
<a name="search_and_replace"></a><h3>
Search and replace</h3>


Searching is demonstrated in Snippet 12, here is a sample how you can search and replace:
<pre>
<code>
	String keywords[] = {"SearchItem1", "SearchItem2"};
	String keyvalues[] = {"ReplaceItem1", "ReplaceItem2"};
		
		
		
		
		for (int keywordIndex = 0; keywordIndex &lt; keywords.length; keywordIndex++) {
			// replace all keywords by their respective keyValues
			
			// noa does not seem to support replacements(XReplaceable), so lets initiate a search and replace the occurences individually
			SearchDescriptor searchDescriptor = new SearchDescriptor(keywords[keywordIndex]);
			searchDescriptor.setIsCaseSensitive(true);
			
			ISearchResult searchResult = this.parentWizard.getDocument().getSearchService().findAll(searchDescriptor);
			
			if(!searchResult.isEmpty()) {
				//...and now select the result
				ITextRange[] textRanges = searchResult.getTextRanges();
				for (int resultIndex=0; resultIndex&lt;textRanges.length; resultIndex++) {
					textRanges[resultIndex].setText(keyvalues[keywordIndex]);
					
				}
			}
		}


</code>
</pre>
		

<a href='#top'>Back to top</a><br/>
<a name="export_pdf"></a><h3>
Export PDF
</h3>
<pre>
<code>

/*
 * Last changes made by $Author: andreas $, $Date: 2006-10-04 14:14:28 +0200 (Mi, 04 Okt 2006) $
 */
import ag.ion.bion.officelayer.application.IOfficeApplication;
import ag.ion.bion.officelayer.application.OfficeApplicationRuntime;

import ag.ion.bion.officelayer.document.IDocument;

import ag.ion.bion.officelayer.filter.PDFFilter;

import java.util.HashMap;

/**
 * This code snippet creates an inpress document
 * and exports the new document to pdf.
 * 
 * @author Andreas Bröker
 * @version $Revision: 10398 $
 * @date 16.03.2006
 */
public class Snippet1 {
	
	public static void main(String args[]) {
		String officeHome = "C:\\Programme\\OpenOffice.org 2.0"; //define your office home here
		String pdfExportPath = "C:\\MyImpressPDF.pdf"; //define your pdf target path
		
		HashMap hashMap = new HashMap(2);
		hashMap.put(IOfficeApplication.APPLICATION_TYPE_KEY, IOfficeApplication.LOCAL_APPLICATION);
		hashMap.put(IOfficeApplication.APPLICATION_HOME_KEY, officeHome);
		
		try {
			IOfficeApplication application = OfficeApplicationRuntime.getApplication(hashMap);
			application.activate();
			IDocument document = application.getDocumentService().constructNewHiddenDocument(IDocument.IMPRESS);
			document.getPersistenceService().export(pdfExportPath, PDFFilter.FILTER);
			application.deactivate();
		}
		catch(Throwable throwable) {
			throwable.printStackTrace();
		}
	}
	
}

</code>
</pre>
<a href='#top'>Back to top</a><br/>
<a name="tables"></a><h3>
Tables</h3>


<pre>
<code>
/*
 * Last changes made by $Author: andreas $, $Date: 2006-10-04 14:14:28 +0200 (Mi, 04 Okt 2006) $
 */
import ag.ion.bion.officelayer.application.IOfficeApplication;
import ag.ion.bion.officelayer.application.OfficeApplicationRuntime;
import ag.ion.bion.officelayer.document.DocumentDescriptor;
import ag.ion.bion.officelayer.document.IDocument;
import ag.ion.bion.officelayer.document.IDocumentService;
import ag.ion.bion.officelayer.text.IText;
import ag.ion.bion.officelayer.text.ITextDocument;
import ag.ion.bion.officelayer.text.ITextTable;

import java.util.HashMap;

/**
 * This code snippet creates a table and makes the first three line table header style.
 * 
 * @author Markus Krüger
 * @version $Revision: 10398 $
 */
public class Snippet16 {

  /*
   * The path to the office application, in this case on a Windows system.
   * 
   * On a (n OpenSUSE)Linux system this would look like: 
   * => private final static String officeHome = "/usr/lib/OpenOffice.org2.1"; 
   */
  private final static String OPEN_OFFICE_ORG_PATH = "C:\\Programme\\OpenOffice.org 2.1"; 
    
  public static void main(String[] args) {
    try {
      HashMap configuration = new HashMap();
      configuration.put(IOfficeApplication.APPLICATION_HOME_KEY, OPEN_OFFICE_ORG_PATH);
      configuration.put(IOfficeApplication.APPLICATION_TYPE_KEY, IOfficeApplication.LOCAL_APPLICATION);
      final IOfficeApplication officeAplication = OfficeApplicationRuntime.getApplication(configuration); 
      officeAplication.setConfiguration(configuration);
      officeAplication.activate();
      IDocumentService documentService = officeAplication.getDocumentService();
      ITextDocument textDocument = (ITextDocument)documentService.constructNewDocument(IDocument.WRITER, DocumentDescriptor.DEFAULT);

      //construct table
      int rows = 15;
      int cols = 5;
      ITextTable textTable = textDocument.getTextTableService().constructTextTable(rows, cols);       
      textDocument.getTextService().getTextContentService().insertTextContent(textTable);
      textTable.setHeaderRows(3);
      //set some text
      for(int i = 0, n = rows; i &lt; n; i++) {
        for(int j = 0, m = cols; j &lt; m; j++) {
          IText cellText = textTable.getCell(j,i).getTextService().getText();
          cellText.setText("Line "+(i+1)+" Col "+(j+1));
        }
      }
    } 
    catch (Throwable exception) {
      exception.printStackTrace();
    } 
  }

}

</code>
</pre>

<a href='#top'>Back to top</a><br/>
<a name="construct_and_fill_table"></a><h3>
Construct and fill table
</h3>

<pre>
<code>
/*
 * Last changes made by $Author: andreas $, $Date: 2006-10-04 14:14:28 +0200 (Mi, 04 Okt 2006) $
 */
import ag.ion.bion.officelayer.application.IOfficeApplication;
import ag.ion.bion.officelayer.application.OfficeApplicationException;
import ag.ion.bion.officelayer.application.OfficeApplicationRuntime;

import ag.ion.bion.officelayer.document.DocumentDescriptor;
import ag.ion.bion.officelayer.document.IDocument;
import ag.ion.bion.officelayer.document.IDocumentService;

import ag.ion.bion.officelayer.text.IText;
import ag.ion.bion.officelayer.text.ITextDocument;
import ag.ion.bion.officelayer.text.ITextService;
import ag.ion.bion.officelayer.text.ITextTable;
import ag.ion.bion.officelayer.text.TextException;

import ag.ion.noa.NOAException;

import java.util.HashMap;

/**
 * This code snippet creates a new text document (like in Snippet2). Furthermore
 * we will place a table in the document and add some content to it.
 * 
 * @author Sebastian Rösgen
 * @version $Revision: 10398 $
 * @date 17.03.2006
 */
public class Snippet5 {

	/*
	 * The path to the office application, in this case on a(n OpenSUSE)Linux system.
	 * 
	 * On a Windows system this would look like: 
	 * => private final static String officeHome = "C:\\Programme\\OpenOffice.org 2.0"; 
	 */
	private final static String OPEN_OFFICE_ORG_PATH = "/usr/lib/ooo-2.0"; 
		
	public static void main(String[] args) {
   	HashMap configuration = new HashMap();
		configuration.put(IOfficeApplication.APPLICATION_HOME_KEY, OPEN_OFFICE_ORG_PATH);
		configuration.put(IOfficeApplication.APPLICATION_TYPE_KEY, IOfficeApplication.LOCAL_APPLICATION);
		
		try {
			IOfficeApplication officeAplication = OfficeApplicationRuntime.getApplication(configuration);
			officeAplication.activate();
			IDocumentService documentService = officeAplication.getDocumentService();
			IDocument document = documentService.constructNewDocument(IDocument.WRITER, DocumentDescriptor.DEFAULT);
			ITextDocument textDocument = (ITextDocument)document;
			textDocument.addCloseListener(new SnippetDocumentCloseListener(officeAplication));
			
			/*
			 * This stuff has already been discussed in Snippet2 but now lets begin to
			 * work with tables in text documents
			 */
			constructAndFillTable(textDocument);

		} 
		catch (OfficeApplicationException exception) {
			exception.printStackTrace();
		} 
		catch (NOAException exception) {
			exception.printStackTrace();
		}
	}
	//----------------------------------------------------------------------------
	/**
	 * The first table example. We will create a table and then place some values in the cells.
	 * 
	 * @param textDocument the document to place the table in
	 *
	 * @author Sebastian Rösgen
	 * @date 17.03.2006
	 */
	public static void constructAndFillTable(ITextDocument textDocument) {
	  try {
			// create the table
			ITextTable textTable = textDocument.getTextTableService().constructTextTable(3, 5);				
			textDocument.getTextService().getTextContentService().insertTextContent(textTable);
		
			// and place some double values in it			
		  textTable.getCell(0,0).setValue(12412);
		  textTable.getCell(0,1).setValue(4444444);
		  
		  // to place text in a cell we need the text service of the individual cell.
		  ITextService textService = textTable.getCell(0,2).getTextService();
		  IText cellText = textService.getText();
		  cellText.setText("Hello World!");
		  
		  // so now that we have seen it in detail, there is no problem in doing
		  // it the short way.
		  textTable.getCell(2,2).getTextService().getText().setText("A");
		  textTable.getCell(3,2).getTextService().getText().setText("Simple");
		  textTable.getCell(4,2).getTextService().getText().setText("Test");
		  
		} 
	  catch (TextException exception) {
	  	exception.printStackTrace();
		}
	}
	//----------------------------------------------------------------------------
	
}
</code>
</pre>

<a href='#top'>Back to top</a><br/>
<a name="more_table_operations"></a><h3>
More table operations
</h3>
<pre>
<code>
/*
 * Last changes made by $Author: andreas $, $Date: 2006-10-04 14:14:28 +0200 (Mi, 04 Okt 2006) $
 */
import ag.ion.bion.officelayer.application.IOfficeApplication;
import ag.ion.bion.officelayer.application.OfficeApplicationException;
import ag.ion.bion.officelayer.application.OfficeApplicationRuntime;

import ag.ion.bion.officelayer.document.DocumentDescriptor;
import ag.ion.bion.officelayer.document.IDocument;
import ag.ion.bion.officelayer.document.IDocumentService;

import ag.ion.bion.officelayer.text.ITextDocument;
import ag.ion.bion.officelayer.text.ITextTable;
import ag.ion.bion.officelayer.text.ITextTableCell;
import ag.ion.bion.officelayer.text.ITextTableRow;
import ag.ion.bion.officelayer.text.TextException;

import ag.ion.noa.NOAException;

import java.util.HashMap;

/**
 * This code snippet creates a new text document and do some stuff with tables.
 * 
 * We will create two tables, put some content in them (iterating through all cells)
 * and then add some new rows and columns to the second table.
 * 
 * @author Sebastian Rösgen
 * @version $Revision: 10398 $
 * @date 17.03.2006
 */
public class Snippet6 {

	/*
	 * The path to the office application, in this case on a(n OpenSUSE)Linux system.
	 * 
	 * On a Windows system this would look like: 
	 * => private final static String officeHome = "C:\\Programme\\OpenOffice.org 2.0"; 
	 */
	private final static String OPEN_OFFICE_ORG_PATH = "/usr/lib/ooo-2.0"; 
		
	public static void main(String[] args) {
		HashMap configuration = new HashMap();
		configuration.put(IOfficeApplication.APPLICATION_HOME_KEY, OPEN_OFFICE_ORG_PATH);
		configuration.put(IOfficeApplication.APPLICATION_TYPE_KEY, IOfficeApplication.LOCAL_APPLICATION);
		
		try {
			IOfficeApplication officeAplication = OfficeApplicationRuntime.getApplication(configuration);
			officeAplication.activate();
			IDocumentService documentService = officeAplication.getDocumentService();
			IDocument document = documentService.constructNewDocument(IDocument.WRITER, DocumentDescriptor.DEFAULT);
			ITextDocument textDocument = (ITextDocument)document;
			textDocument.addCloseListener(new SnippetDocumentCloseListener(officeAplication));
			
			/*
			 * This stuff was already discussed in Snippet2 but now lets begin to
			 * work with tables in text documents
			 */
			constructAndFillTables(textDocument);

		} 
		catch (OfficeApplicationException exception) {
			exception.printStackTrace();
		} 
		catch (NOAException exception) {
			exception.printStackTrace();
		}
	}
	//----------------------------------------------------------------------------
	/**
	 * The second table example. We will place some content in the table, after the creation.
	 * 
	 * @param textDocument the document to place the table in
	 *
	 * @author Sebastian Rösgen
	 * @date 17.03.2006
	 */
	public static void constructAndFillTables(ITextDocument textDocument) {
	  try {
			// create the first table
			ITextTable firstTextTable = textDocument.getTextTableService().constructTextTable(3, 5);				
			textDocument.getTextService().getTextContentService().insertTextContent(firstTextTable);
		
			int firstTableRowCount = firstTextTable.getRowCount();
			int firstTableColumnCount = firstTextTable.getColumnCount();
			
			int counter=0; // just to fill some value inside the cells
			
			// we will just fill it with double values
			for(int i=0;i&lt;firstTableRowCount;i++) {
				for(int j=0;j&lt;firstTableColumnCount;j++) {
					firstTextTable.getCell(j,i).setValue(++counter);
				}
			}
			
			// create the second table
			ITextTable secondTextTable = textDocument.getTextTableService().constructTextTable(4, 4);				
			textDocument.getTextService().getTextContentService().insertTextContent(secondTextTable);
			ITextTableRow[] rows = secondTextTable.getRows();
			
			// we will iterate through it in a different manner than before
			for(int i=0;i&lt;rows.length;i++) {
				ITextTableRow currentRow = rows[i];
				ITextTableCell[] cellsOfRow = currentRow.getCells();
				for(int j=0;j&lt;cellsOfRow.length;j++) {
					String cellContent = "Column: " + (j+1) + " Row: " + (i+1);
					//that which follows is alrady known from Snippet3
					cellsOfRow[j].getTextService().getText().setText(cellContent);
				}
			}
			
			// add two new rows at the end of the table
			secondTextTable.addRow(2);
			
			// add a new row after the second row
			secondTextTable.addRow(2,1);
								  
		} 
	  catch (TextException exception) {
	  	exception.printStackTrace();
		}
	}
	//----------------------------------------------------------------------------
	
}
</code>
</pre>

<a href='#top'>Back to top</a><br/>
<a name="formulas_in_writer_tables"></a><h3>
Formulas in Writer tables</h3>
<pre>
<code>
/*
 * Last changes made by $Author: andreas $, $Date: 2006-10-04 14:14:28 +0200 (Mi, 04 Okt 2006) $
 */
import ag.ion.bion.officelayer.application.IOfficeApplication;
import ag.ion.bion.officelayer.application.OfficeApplicationException;
import ag.ion.bion.officelayer.application.OfficeApplicationRuntime;

import ag.ion.bion.officelayer.document.DocumentDescriptor;
import ag.ion.bion.officelayer.document.IDocument;
import ag.ion.bion.officelayer.document.IDocumentService;

import ag.ion.bion.officelayer.text.ITextDocument;
import ag.ion.bion.officelayer.text.ITextTable;
import ag.ion.bion.officelayer.text.ITextTableCell;
import ag.ion.bion.officelayer.text.ITextTableColumn;
import ag.ion.bion.officelayer.text.ITextTableRow;
import ag.ion.bion.officelayer.text.TextException;

import ag.ion.noa.NOAException;

import java.util.HashMap;

/**
 * In here we will do some more stuff with tables especially with formulas.
 *  
 * @author Sebastian Rösgen
 * @version $Revision: 10398 $
 * @date 17.03.2006
 */
public class Snippet11 {

	/*
	 * The path to the office application, in this case on a(n OpenSUSE)Linux system.
	 * 
	 * On a Windows system this would look like: 
	 * => private final static String officeHome = "C:\\Programme\\OpenOffice.org 2.0"; 
	 */
	private final static String OPEN_OFFICE_ORG_PATH = "/usr/lib/ooo-2.0"; 
		
	public static void main(String[] args) {
		DocumentDescriptor documentDescriptor = new DocumentDescriptor();
		documentDescriptor.setHidden(false); // set hidden=false so that the document is opened
		
		HashMap configuration = new HashMap();
		configuration.put(IOfficeApplication.APPLICATION_HOME_KEY, OPEN_OFFICE_ORG_PATH);
		configuration.put(IOfficeApplication.APPLICATION_TYPE_KEY, IOfficeApplication.LOCAL_APPLICATION);
		
		try {
			IOfficeApplication officeAplication = OfficeApplicationRuntime.getApplication(configuration);
			officeAplication.activate();
			IDocumentService documentService = officeAplication.getDocumentService();
			IDocument document = documentService.constructNewDocument("TestDocument",documentDescriptor);
			ITextDocument textDocument = (ITextDocument)document;
			textDocument.addCloseListener(new SnippetDocumentCloseListener(officeAplication));
			
			/*
			 * This stuff was already discussed in Snippet2 but now lets begin to
			 * work with tables in text documents
			 */
			constructAndFillTables(textDocument);

		} 
		catch (OfficeApplicationException exception) {
			exception.printStackTrace();
		} 
		catch (NOAException exception) {
			exception.printStackTrace();
		}
	}
	//----------------------------------------------------------------------------
	/**
	 * A table example in which we will create a table and the let calculate the
	 * sum of each column.
	 * 
	 * @param textDocument the document to place the table in
	 *
	 * @author Sebastian Rösgen
	 * @date 17.03.2006
	 */
	public static void constructAndFillTables(ITextDocument textDocument) {
	  try {
			// create the first table
			ITextTable textTable = textDocument.getTextTableService().constructTextTable(3, 5);				
			textDocument.getTextService().getTextContentService().insertTextContent(textTable);
		
			int tableRowCount = textTable.getRowCount();
			int tableColumnCount = textTable.getColumnCount();
			
			int counter=0; // just to fill some value inside the cells
			
			// we will just fill it with double values
			for(int i=0;i&lt;tableRowCount;i++) {
				for(int j=0;j&lt;tableColumnCount;j++) {
					textTable.getCell(j,i).setValue(++counter);
				}
			}
			
			// add a new row at the end of the table
			textTable.addRow(1);
			
			ITextTableRow row = textTable.getRow(textTable.getRowCount()-1);
			ITextTableColumn[] columns = textTable.getColumns();
			// we want the sum of each column in the last row
			for(int i=0;i&lt;columns.length;i++) {
				ITextTableCell[][] cells = columns[i].getCellRange().getCells();
				
				//we need all but the last cell in the column (the last will be the formula)				
				StringBuffer cellNames = new StringBuffer();				
				for(int x=0;x&lt;cells.length-1;x++) {
						cellNames.append("<"+cells[x][0].getName().getName()+">");
						if(x&lt;cells.length-2) {
							cellNames.append("+");
						}
				}
				
				ITextTableCell formulaCell= row.getCells()[i];
				formulaCell.getFormulaService().setFormula(cellNames.toString());
			}
		} 
	  catch (TextException exception) {
	  	exception.printStackTrace();
		}
	}
	//----------------------------------------------------------------------------
	
}
</code>
</pre>

<a href='#top'>Back to top</a><br/>
<a name="add_images"></a><h3>
Add images
</h3>

<pre>
<code>
/*
 * Last changes made by $Author: andreas $, $Date: 2006-10-04 14:14:28 +0200 (Mi, 04 Okt 2006) $
 */
import ag.ion.bion.officelayer.application.IOfficeApplication;
import ag.ion.bion.officelayer.application.OfficeApplicationException;
import ag.ion.bion.officelayer.application.OfficeApplicationRuntime;
import ag.ion.bion.officelayer.document.DocumentDescriptor;
import ag.ion.bion.officelayer.document.IDocument;
import ag.ion.bion.officelayer.document.IDocumentService;
import ag.ion.bion.officelayer.text.ITextContentService;
import ag.ion.bion.officelayer.text.ITextCursor;
import ag.ion.bion.officelayer.text.ITextDocument;
import ag.ion.bion.officelayer.text.ITextDocumentImage;
import ag.ion.noa.graphic.GraphicInfo;

import com.sun.star.text.HoriOrientation;
import com.sun.star.text.TextContentAnchorType;
import com.sun.star.text.VertOrientation;

import java.io.FileInputStream;
import java.util.HashMap;

/** 
 * This code snippet creates an image inside a text document. 
 *  
 * @author Markus Krüger
 * @version $Revision: 10398 $ 
 */
public class Snippet17 {

  /* 
   * The path to the office application, in this case on a(n OpenSUSE)Linux system. On a Windows system this 
   * would look like: => private final static String officeHome = "C:\\Programme\\OpenOffice.org 2.0"; 
   */
  private final static String OPEN_OFFICE_ORG_PATH = "C:\\Programme\\OpenOffice.org 2.2";

  public static void main(String[] args) {
    try {
      HashMap configuration = new HashMap();
      configuration.put(IOfficeApplication.APPLICATION_HOME_KEY,
          OPEN_OFFICE_ORG_PATH);
      configuration.put(IOfficeApplication.APPLICATION_TYPE_KEY,
          IOfficeApplication.LOCAL_APPLICATION);
      final IOfficeApplication officeAplication = OfficeApplicationRuntime
          .getApplication(configuration);
      officeAplication.setConfiguration(configuration);
      officeAplication.activate();
      IDocumentService documentService = officeAplication.getDocumentService();
      IDocument document = documentService.constructNewDocument(
          IDocument.WRITER, new DocumentDescriptor());

      ITextDocument textDocument = (ITextDocument) document;

      boolean useStream = true;
      GraphicInfo graphicInfo = null;

      String imagePath = "d:\\my_image.gif";
      int pixelWidth = 265;
      int pixelHeight = 256;

      if(!useStream) {
        //with url
        graphicInfo = new GraphicInfo(imagePath, pixelWidth, true, pixelHeight, true,
            VertOrientation.TOP, HoriOrientation.LEFT,
            TextContentAnchorType.AT_PARAGRAPH);
      }
      else {
        //with stream
        graphicInfo = new GraphicInfo(new FileInputStream(imagePath), pixelWidth,
            true, pixelHeight, true, VertOrientation.TOP, HoriOrientation.LEFT,
            TextContentAnchorType.AT_PARAGRAPH);
      }

      ITextContentService textContentService = textDocument.getTextService()
          .getTextContentService();

      ITextCursor textCursor = textDocument.getTextService().getText()
          .getTextCursorService().getTextCursor();

      ITextDocumentImage textDocumentImage = textContentService
          .constructNewImage(graphicInfo);
      textContentService.insertTextContent(textCursor.getEnd(),
          textDocumentImage);

      officeAplication.deactivate();
    }
    catch(OfficeApplicationException exception) {
      exception.printStackTrace();
    }
    catch(Throwable exception) {
      exception.printStackTrace();
    }
  }

}
</code>
</pre>


<a href='#top'>Back to top</a><br/>
<a name="iterate_over_paragraphs_set_their_alignment"></a><h3>
Iterate over paragraphs, set their alignment
</h3>
<pre>
<code>
/*
 * Last changes made by $Author: andreas $, $Date: 2006-10-04 14:14:28 +0200 (Mi, 04 Okt 2006) $
 */
import ag.ion.bion.officelayer.application.IOfficeApplication;
import ag.ion.bion.officelayer.application.OfficeApplicationException;
import ag.ion.bion.officelayer.application.OfficeApplicationRuntime;

import ag.ion.bion.officelayer.document.DocumentDescriptor;
import ag.ion.bion.officelayer.document.IDocument;
import ag.ion.bion.officelayer.document.IDocumentService;

import ag.ion.bion.officelayer.text.IParagraph;
import ag.ion.bion.officelayer.text.IParagraphProperties;
import ag.ion.bion.officelayer.text.ITextCursor;
import ag.ion.bion.officelayer.text.ITextDocument;
import ag.ion.bion.officelayer.text.TextException;

import ag.ion.noa.NOAException;

import java.util.HashMap;

/**
 * In this snippet we will do some text formatting. 
 * 
 * @author Sebastian Rösgen
 * @version $Revision: 10398 $
 * @date 17.03.2006
 */
public class Snippet8 {

	/*
	 * The path to the office application, in this case on a(n OpenSUSE)Linux system.
	 * 
	 * On a Windows system this would look like: 
	 * => private final static String officeHome = "C:\\Programme\\OpenOffice.org 2.0"; 
	 */
	private final static String OPEN_OFFICE_ORG_PATH = "/usr/lib/ooo-2.0"; 
	
	
	public static void main(String[] args) {
		HashMap configuration = new HashMap();
		configuration.put(IOfficeApplication.APPLICATION_HOME_KEY, OPEN_OFFICE_ORG_PATH);
		configuration.put(IOfficeApplication.APPLICATION_TYPE_KEY, IOfficeApplication.LOCAL_APPLICATION);
		
		try {
			IOfficeApplication officeAplication = OfficeApplicationRuntime.getApplication(configuration);
			officeAplication.activate();
			IDocumentService documentService = officeAplication.getDocumentService();
			IDocument document = documentService.constructNewDocument(IDocument.WRITER, DocumentDescriptor.DEFAULT);
			ITextDocument textDocument = (ITextDocument)document;
			textDocument.addCloseListener(new SnippetDocumentCloseListener(officeAplication));

			/*
			 * Now do the work with text content.
			 */
			placeSomeTextContent(textDocument);

		} 
		catch (OfficeApplicationException exception) {
			exception.printStackTrace();
		} 
		catch (NOAException exception) {
			exception.printStackTrace();
		}
	}
	//----------------------------------------------------------------------------
	/**
	 * We will now format the text, we create, a little bit.
	 * 
	 * @param textDocument the document to place the table in
	 *
	 * @author Sebastian Rösgen
	 * @date 17.03.2006
	 */
	public static void placeSomeTextContent(ITextDocument textDocument) {
	  	
  	String[] text2BePlaced = { 
  		"The Raven (excerpt)\n",
			"",
			"...",
			"...",
			"",
			"But the raven, sitting lonely on the placid bust, spoke only,",
			"That one word, as if his soul in that one word he did outpour.",
			"Nothing further then he uttered - not a feather then he fluttered -",
			"Till I scarcely more than muttered `Other friends have flown before -",
			"On the morrow will he leave me, as my hopes have flown before.'",
			"Then the bird said, `Nevermore.'",
			"",
			"Startled at the stillness broken by reply so aptly spoken,",
			"`Doubtless,' said I, `what it utters is its only stock and store,",
			"Caught from some unhappy master whom unmerciful disaster",
			"Followed fast and followed faster till his songs one burden bore -",
			"Till the dirges of his hope that melancholy burden bore",
			"Of \"Never-nevermore.\"'"
  	};
  	
  	try {
	  	ITextCursor textCursor = 
	  		textDocument.getTextService().getText().getTextCursorService().getTextCursor();
	  	
	  	textCursor.gotoEnd(false);
	  	
	  	for(int i=0;i&lt;text2BePlaced.length;i++ ) {
	  		textCursor.getEnd().setText(text2BePlaced[i]); //we place the text
	  		textCursor.getEnd().setText("\n"); // and we wrap the line
	  	}
	  	
	  	// Now some new stuff. We will set the align of the poem -- which should be centered
	  	// as it fits for a good poem -- afterwards we will	  	
	  	IParagraph[] paragraphs = 
	  		textDocument.getTextService().getText().getTextContentEnumeration().getParagraphs();
	  	
	  	
	  	// there should be only one paragraph, since we did not insert any additional ones
	  	// so we use index 0 of the array.	  	
	  	IParagraphProperties paragraphPropoerties = paragraphs[0].getParagraphProperties();
	  	paragraphPropoerties.setParaAdjust(IParagraphProperties.ALIGN_CENTER);
	  	
	  	// set the font bold and italic, set size to 9 and color the text blue, 
	  	paragraphPropoerties.getCharacterProperties().setFontBold(true);
	  	paragraphPropoerties.getCharacterProperties().setFontSize(9);
	  	paragraphPropoerties.getCharacterProperties().setFontItalic(true);
	  	paragraphPropoerties.getCharacterProperties().setFontColor(150);
	  	
	  }
  	catch(TextException exception) {
  		exception.printStackTrace();
  	}

	}
	//----------------------------------------------------------------------------
	
}
</code>
</pre>

<a href='#top'>Back to top</a><br/>
<a name="ui_disable_commands"></a><h3>
UI: Disable commands</h3>

If you embed e.g. OpenOffice Writer, it will be necessary to handle - or disable Writers "close" and "quit" functionality.<br/>
<a href='../examples/ui/Snippet14.java'>Snippet14</a> shows how to disable commands, namely using
<pre>
<code>
      //Now it is time to disable two commands in the frame
      officeFrame.disableDispatch(GlobalCommands.CLOSE_DOCUMENT);
      officeFrame.disableDispatch(GlobalCommands.QUIT_APPLICATION);
      officeFrame.updateDispatches();
</code>
</pre>

<a name="calc"></a>
<h2>OpenOffice Calc</h2>


<a href='#top'>Back to top</a><br/>
<a name="spreadsheet"></a><h3>
Spreadsheet
</h3>
See <a href="#step3">step 3</a> of the tutorial how to embed a Calc document.
Of course officeApplication.getDocumentService().constructNewDocument will construct a new document, you could as well load one by using (analogue to writer documents).
See <a href="../examples/calc/Snippet19-load.java">Snippet19</a>:
<pre>
<code>
			document = /* (3f) */(ISpreadsheetDocument) officeApplication
					.getDocumentService().loadDocument(officeFrame, "C:\\Users\\jstaerk\\Documents\\finanzen.ods", DocumentDescriptor.DEFAULT);

</code>
</pre>

<a href='#top'>Back to top</a><br/>
<a name="find_cell_by_name_set_formula"></a><h3>
Find cell by name, set formula
</h3>


According to Markus on http://ubion.ion.ag/mainForumFolder/noa_forum/0199?b_start:int=0#0016, this source will create a OpenOffice.org Calc window in a SWING frame
<pre>
<code>
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.HashMap;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import ag.ion.bion.officelayer.NativeView;
import ag.ion.bion.officelayer.application.IApplicationAssistant;
import ag.ion.bion.officelayer.application.ILazyApplicationInfo;
import ag.ion.bion.officelayer.application.IOfficeApplication;
import ag.ion.bion.officelayer.application.OfficeApplicationRuntime;
import ag.ion.bion.officelayer.desktop.IFrame;
import ag.ion.bion.officelayer.document.DocumentDescriptor;
import ag.ion.bion.officelayer.document.IDocument;
import ag.ion.bion.officelayer.internal.application.ApplicationAssistant;
import ag.ion.bion.officelayer.spreadsheet.ISpreadsheetDocument;
import ag.ion.bion.officelayer.text.table.TextTableCellNameHelper;

import com.sun.star.sheet.XSheetCellCursor;
import com.sun.star.sheet.XSpreadsheet;
import com.sun.star.sheet.XSpreadsheets;
import com.sun.star.table.XCell;
import com.sun.star.text.XText;
import com.sun.star.uno.UnoRuntime;

public class SimpleApp extends JFrame {

  private static final String  CELL_NAME         = "C1";
  private static final String  SHEET_NAME        = "Tabelle1"; //or Table1

  private IOfficeApplication   officeApplication = null;
  private IFrame               officeFrame       = null;
  private ISpreadsheetDocument document          = null;
  private JPanel               noaPanel          = null;
  private JTextField           textField         = null;

  public SimpleApp() {
    super(SimpleApp.class.getName());
    getContentPane().setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();

    JLabel label = new JLabel("Value: ");
    c.fill = GridBagConstraints.HORIZONTAL;
    c.insets = new Insets(10, 0, 0, 0);
    c.weightx = 0.1;
    c.gridx = 0;
    c.gridy = 0;
    getContentPane().add(label, c);
    textField = new JTextField();
    label.setLabelFor(textField);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.weightx = 0.7;
    c.gridx = 1;
    c.gridy = 0;
    getContentPane().add(textField, c);
    JButton buttonRead = new JButton("Read Value Of " + CELL_NAME);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.weightx = 0.1;
    c.gridx = 2;
    c.gridy = 0;
    getContentPane().add(buttonRead, c);

    buttonRead.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        try {
          XSpreadsheets sheets = document.getSpreadsheetDocument().getSheets();
          XSpreadsheet spreadsheet1 = (XSpreadsheet) UnoRuntime.queryInterface(XSpreadsheet.class,
              sheets.getByName(SHEET_NAME));
          XSheetCellCursor cellCursor = spreadsheet1.createCursor();
          XCell cell = cellCursor.getCellByPosition(TextTableCellNameHelper.getColumnIndex(CELL_NAME),
              TextTableCellNameHelper.getRowIndex(CELL_NAME));
          XText cellText = (XText) UnoRuntime.queryInterface(XText.class, cell);
          textField.setText(cellText.getString());
        }
        catch (Exception exception) {
          exception.printStackTrace();
        }
      }
    });

    JButton buttonReadFormula = new JButton("Read Formula Of " + CELL_NAME);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.weightx = 0.1;
    c.gridx = 3;
    c.gridy = 0;
    getContentPane().add(buttonReadFormula, c);

    buttonReadFormula.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        try {
          XSpreadsheets sheets = document.getSpreadsheetDocument().getSheets();
          XSpreadsheet spreadsheet1 = (XSpreadsheet) UnoRuntime.queryInterface(XSpreadsheet.class,
              sheets.getByName(SHEET_NAME));
          XSheetCellCursor cellCursor = spreadsheet1.createCursor();
          XCell cell = cellCursor.getCellByPosition(TextTableCellNameHelper.getColumnIndex(CELL_NAME),
              TextTableCellNameHelper.getRowIndex(CELL_NAME));
          String formula = cell.getFormula();
          if (formula != null && formula.startsWith("=")) {
            textField.setText(formula);
          }
          else {
            textField.setText("NO FORMULA");
          }
        }
        catch (Exception exception) {
          exception.printStackTrace();
        }
      }
    });

    JButton buttonUpdate = new JButton("Update Formula/Value Of " + CELL_NAME);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.weightx = 0.1;
    c.gridx = 4;
    c.gridy = 0;
    getContentPane().add(buttonUpdate, c);

    buttonUpdate.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        try {
          XSpreadsheets sheets = document.getSpreadsheetDocument().getSheets();
          XSpreadsheet spreadsheet1 = (XSpreadsheet) UnoRuntime.queryInterface(XSpreadsheet.class,
              sheets.getByName(SHEET_NAME));
          XSheetCellCursor cellCursor = spreadsheet1.createCursor();
          XCell cell = cellCursor.getCellByPosition(TextTableCellNameHelper.getColumnIndex(CELL_NAME),
              TextTableCellNameHelper.getRowIndex(CELL_NAME));
          XText cellText = (XText) UnoRuntime.queryInterface(XText.class, cell);
          String valueStr = textField.getText();
          Object valueObj = valueStr;
          try {
            valueObj = Double.valueOf(Double.parseDouble(valueStr));
          }
          catch (NumberFormatException nfe) {
            //nu number
          }
          if (valueObj instanceof Double)
            cell.setValue(((Double) valueObj).doubleValue());
          else if (valueStr.startsWith("="))
            cell.setFormula(valueStr);
          else
            cellText.setString(valueStr);
        }
        catch (Exception exception) {
          exception.printStackTrace();
        }
      }
    });

    JButton buttonNewDoc = new JButton("Open new Document/Close old one");
    c.fill = GridBagConstraints.HORIZONTAL;
    c.weightx = 0.1;
    c.gridx = 5;
    c.gridy = 0;
    getContentPane().add(buttonNewDoc, c);

    buttonNewDoc.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        try {
          IDocument oldDoc = document;
          document = (ISpreadsheetDocument) officeApplication.getDocumentService().constructNewDocument(officeFrame,
              IDocument.CALC,
              DocumentDescriptor.DEFAULT);
          oldDoc.close();
        }
        catch (Exception exception) {
          exception.printStackTrace();
        }
      }
    });

    noaPanel = new JPanel();
    c.weighty = 1.0;
    c.anchor = GridBagConstraints.PAGE_END;
    c.insets = new Insets(10, 0, 0, 0);
    c.fill = GridBagConstraints.BOTH;
    c.gridx = 0;
    c.gridy = 1;
    c.gridwidth = 6;
    getContentPane().add(noaPanel, c);
    setSize(1024, 800);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
    fillNOAPanel();
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent windowEvent) {
        try {
          if (document != null)
            document.close();
          document = null;
          /*if (officeApplication != null) {
            officeApplication.deactivate();
            officeApplication.dispose();
            officeApplication = null;
          }*/
        }
        catch (Exception exception) {
          //do not consume
        }
      }
    });
  }

  private void fillNOAPanel() {
    if (noaPanel != null) {
      try {
        if (officeApplication == null)
          officeApplication = startOOO();
        officeFrame = constructOOOFrame(officeApplication, noaPanel);
        document = (ISpreadsheetDocument) officeApplication.getDocumentService().constructNewDocument(officeFrame,
            IDocument.CALC,
            DocumentDescriptor.DEFAULT);

        noaPanel.setVisible(true);
      }
      catch (Throwable throwable) {
        noaPanel.add(new JLabel("An error occured while creating the NOA panel: " + throwable.getMessage()));
      }
    }
  }

  private IOfficeApplication startOOO() throws Throwable {
    IApplicationAssistant applicationAssistant = new ApplicationAssistant(System.getProperty("user.dir") + "\\lib");
    ILazyApplicationInfo[] appInfos = applicationAssistant.getLocalApplications();
    if (appInfos.length &lt; 1)
      throw new Throwable("No OpenOffice.org Application found.");
    HashMap configuration = new HashMap();
    configuration.put(IOfficeApplication.APPLICATION_HOME_KEY, appInfos[0].getHome());
    configuration.put(IOfficeApplication.APPLICATION_TYPE_KEY, IOfficeApplication.LOCAL_APPLICATION);
    IOfficeApplication officeAplication = OfficeApplicationRuntime.getApplication(configuration);

    officeAplication.setConfiguration(configuration);
    officeAplication.activate();
    return officeAplication;
  }

  private IFrame constructOOOFrame(IOfficeApplication officeApplication, final Container parent)
      throws Throwable {
    final NativeView nativeView = new NativeView(System.getProperty("user.dir") + "\\lib");
    parent.add(nativeView);
    parent.addComponentListener(new ComponentAdapter() {
      public void componentResized(ComponentEvent e) {
        nativeView.setPreferredSize(new Dimension(parent.getWidth() - 5, parent.getHeight() - 5));
        parent.getLayout().layoutContainer(parent);
      }
    });
    nativeView.setPreferredSize(new Dimension(parent.getWidth() - 5, parent.getHeight() - 5));
    parent.getLayout().layoutContainer(parent);
    IFrame officeFrame = officeApplication.getDesktopService().constructNewOfficeFrame(nativeView);
    parent.validate();
    return officeFrame;
  }

  public static void main(String[] argv) {
    new SimpleApp();
  }
}

</code>
</pre>
<a name="base"></a>
<h2>OpenOffice Base</h2>
<a href='#top'>Back to top</a><br/>
<a name="base_basics"></a><h3>
Base basics
</h3>
<pre>
<code>
import ag.ion.bion.officelayer.application.IOfficeApplication;
import ag.ion.bion.officelayer.application.OfficeApplicationRuntime;

import ag.ion.bion.officelayer.document.IDocument;

import java.util.HashMap;

/**
 * This code snippet creates a base document
 * and stores it.
 * 
 * @author Andreas Bröker
 * @version $Revision: 10398 $
 * @date 16.03.2006
 */
public class Snippet13 {
	
	public static void main(String args[]) {		
		String officeHome = "C:\\Programme\\OpenOffice.org 2.0"; //define your office home here
		String storePath = "C:\\MyDB.odb"; //define your db target path
		
		HashMap hashMap = new HashMap(2);
		hashMap.put(IOfficeApplication.APPLICATION_TYPE_KEY, IOfficeApplication.LOCAL_APPLICATION);
		hashMap.put(IOfficeApplication.APPLICATION_HOME_KEY, officeHome);

		try {
			IOfficeApplication application = OfficeApplicationRuntime.getApplication(hashMap);
			application.activate();
			IDocument document = application.getDocumentService().constructNewHiddenDocument(IDocument.BASE);
			
			document.getPersistenceService().store(storePath);
			application.deactivate();
			application.dispose();
		}
		catch(Throwable throwable) {
			throwable.printStackTrace();
		}
	}
	
}
</code>
</pre>


<a href='#top'>Back to top</a><br/>
<a name='license'></a>
<h1>License</h1>
<pre>
/****************************************************************************
 *                                                                          *
 * NOA-Libre                                        						*
 * ------------------------------------------------------------------------ *
 *                                                                          *
 * The Contents of this file are made available subject to                  *
 * the terms of GNU Lesser General Public License Version 2.1.              *
 *                                                                          * 
 * GNU Lesser General Public License Version 2.1                            *
 * ======================================================================== *
 * Copyright 2013 by NOA-Libre                                              *
 *                                                                          *
 * This library is free software; you can redistribute it and/or            *
 * modify it under the terms of the GNU Lesser General Public               *
 * License version 2.1, as published by the Free Software Foundation.       *
 *                                                                          *
 * This library is distributed in the hope that it will be useful,          *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        *
 * Lesser General Public License for more details.                          *
 *                                                                          *
 * You should have received a copy of the GNU Lesser General Public         *
 * License along with this library; if not, write to the Free Software      *
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,                    *
 * MA  02111-1307  USA                                                      *
 *                                                                          *
 * Contact us:                                                              *
 *  http://code.google.com/p/noa-libre/										*
 *                                                                          *
 ****************************************************************************/
</pre>

NOA-Libre is based on <a href="http://ubion.ion.ag/loesungen/004niceofficeaccess">Nice Office Access</a>, NOA, gratefully LGPLed by the ION AG.<br/>
Parts of this documentation were based on the LGPLed NOA example files (snippets) and 
on public <a href='http://ubion.ion.ag/mainForumFolder/noa_forum'>forum</a> entries collected by Jochen Stärk on <a href='http://www.usegroup.de/software/noa/'>his wiki</a>.

</body>
</html>
